package com.github.jwt;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Throwables;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * keycloak token验证处理
 *
 * @author inspur_ict
 */
public class KeycloakTokenValidate
{
    private static Logger log = LoggerFactory.getLogger(KeycloakTokenValidate.class);


    /**
     * 获取 RSAPublicKey
     *
     * @param pubKey base64加密公钥
     */
    private static RSAPublicKey getRSAPublicKey(String pubKey) throws NoSuchAlgorithmException {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(pubKey));
        RSAPublicKey publicKey = null;
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        try {
            publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
        } catch (Exception e) {
            log.error("get RSAPublicKey fail ,pubKey:[{}] ,err:[{}]", pubKey, Throwables.getStackTraceAsString(e));
        }
        return publicKey;
    }

    /**
     * 获取 RSAPrivateKey
     *
     * @param priKey base64加密私钥
     */
    private static RSAPrivateKey getRSAPrivateKey(String priKey) throws NoSuchAlgorithmException {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(priKey));
        RSAPrivateKey privateKey = null;
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        try {
            privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        } catch (Exception e) {
            log.error("get RSAPrivateKey fail ,priKey:[{}], err:[{}]", priKey, Throwables.getStackTraceAsString(e));
        }
        return privateKey;
    }


    public static void main(String[] args) throws NoSuchAlgorithmException {
        String token =   "eyJhbGciOiJSUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJMNHJ3R3lQM1dOTEpWSHA1VGlwVXhSdndFbk9zZHp5d2Q4Q1dQYzY5RUFFIn0.eyJleHAiOjE2MzExNTQ5NTUsImlhdCI6MTYzMTE1NDY1NSwianRpIjoiYTI0OGM1MTctN2YzMy00YzEwLWFiNTktMzM4OTM1OTlhZTY1IiwiaXNzIjoiaHR0cDovLzEyNy4wLjAuMTo4MTgwL2F1dGgvcmVhbG1zL2RlbW8iLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZjphZjljNjkzMS02OWFjLTQ3MDEtOTA1ZS1mNWE0MjQ1Yjg5ZGQ6MSIsInR5cCI6IkJlYXJlciIsImF6cCI6InNwcmluZ2Jvb3QiLCJzZXNzaW9uX3N0YXRlIjoiNGVkZDA0YjQtOTEwYy00Yjk0LTkzMjctOTY2ZmI3MzlkMTJhIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwOi8vMTI3LjAuMC4xOjgxODAvIiwiaHR0cDovLzEyNy4wLjAuMS8iXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iLCJ1c2VyIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwaG9uZSBlbWFpbCBwcm9maWxlIiwic2lkIjoiNGVkZDA0YjQtOTEwYy00Yjk0LTkzMjctOTY2ZmI3MzlkMTJhIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbjEiLCJsb2NhbGUiOiJ6aC1DTiIsImVtYWlsIjoiMjc4MDMwMTAzQHFxLmNvbSJ9Cg.g0c_NEyOv0djKKlDcmEB78mUi0lxpO4QEhkOmPdzNTFYOCgyV_I5g36KXry8bSnv0TVH--LcbQMeK0LSWpemSEP6Y0Fo_Rx6SrBmY8bdlSrFYRNsYHHdBFaimgRRkM5xye22VA-xOnoLNPsGX4bTkhUZZ4n7C6GPZ0G9ECAo4bmzwF3bKpSGPJ5_E57be4Py-UkMFMWvb7Jw26CjlizSnFOgNSgTjl5v_qsEBSlVggvcf5j2pw3LJlcqYsGm0NgRRd7B3UZnrn93AyNZEFRV4BnXeJXCFCSAcZVDkhrCzY0MAvHluB61hnFV-UvRMKWzS2DwQO90cRsq3ORd1qAgQQ";
        // token为keycloak加密算法对应的公钥
        String secret = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhergNkCalcfUGSY5aa5NhkkN7EBtZ24B5UetRu8KL1p6idxPb3JkScUyGoDLPKQlo0VNCaojEzjzk2otqhqRXlAghL4LJLj4JJMsXbnMr+ibdMVqXtN6DSgJYCC7fNpnr2LweljGKSNppBhfN9FffLCeAkmNxNn6K3G0ZHd1LScKbmLWKtPUqJxO+gdJaUYMDvhaOLpAz8WhwpAD3YSQK4CDvcjV1yhXfU3Z3SXZAwg4eDfTK4rg32ggaMEwdUCLP4IbaI7l0bIvvPJFYsF4HyNbY7XhY46X47rqqEg+Wyw1eiyL047nS2EVrph05e2h3r0iU2JjUERz4nHb3tYAiwIDAQAB";
        Claims body = Jwts.parser()
                .setSigningKey(getRSAPublicKey(secret))
                .parseClaimsJws(token)
                .getBody();

        System.out.println(JSON.toJSONString(body));

        String changebody = Base64.encodeBase64String("{\"exp\":1631154955,\"iat\":1631154655,\"jti\":\"a248c517-7f33-4c10-ab59-33893599ae65\",\"iss\":\"http://127.0.0.1:8180/auth/realms/demo\",\"aud\":\"account\",\"sub\":\"f:af9c6931-69ac-4701-905e-f5a4245b89dd:1\",\"typ\":\"Bearer\",\"azp\":\"springboot\",\"session_state\":\"4edd04b4-910c-4b94-9327-966fb739d12a\",\"acr\":\"1\",\"allowed-origins\":[\"http://127.0.0.1:8180/\",\"http://127.0.0.1/\"],\"realm_access\":{\"roles\":[\"offline_access\",\"uma_authorization\",\"user\"]},\"resource_access\":{\"account\":{\"roles\":[\"manage-account\",\"manage-account-links\",\"view-profile\"]}},\"scope\":\"phone email profile\",\"sid\":\"4edd04b4-910c-4b94-9327-966fb739d12a\",\"email_verified\":false,\"preferred_username\":\"admin1\",\"locale\":\"zh-CN\",\"email\":\"278030103@qq.com\"}\n".getBytes());
        System.out.println(changebody);
    }

}
